package com.langtags.gears;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.filechooser.FileFilter;

public class ExportJarDemo extends JPanel{
	private JFrame frame;
	private JFileChooser chooser;
	private JTextField srcJarField;
	private JTextField targetJarDirField;
	
  private JLabel databaseLabel;
  private JTextField databaseField;
  private JLabel factoryLabel;
  private JTextField factoryField;
  private JLabel fileSubmitterLabel;
  private JTextField fileSubmitterField;
  private JLabel localServerLabel;
  private JTextField localServerField;
  private JLabel managedResourceStoreLabel;
  private JTextField managedResourceStoreField;
  private JLabel resourceStoreLabel;
  private JTextField resourceStoreField;
  private JLabel resultSetLabel;
  private JTextField resultSetField;
  private JLabel workerPoolLabel;
  private JTextField workerPoolField;

	ExportJarDemo(){
		
		
		chooser = new JFileChooser();
		
		
		setLayout(new BoxLayout(this,
				BoxLayout.Y_AXIS));
		createVarPanel(this);
		createFilePanel();
		createButtonPanel();
	}
	private void createButtonPanel(){
		JPanel panel = new JPanel(false);
		JButton generateButton = new JButton();
		generateButton.setText("Generate");
		panel.setLayout(new BoxLayout(panel,
				BoxLayout.X_AXIS));
		generateButton.addActionListener(new GenerateAction());
		panel.add(generateButton);
		add(panel);
	}
	private void createFilePanel(){
		JPanel filePanel = new JPanel(false);
		filePanel.setLayout(new BoxLayout(filePanel,
				BoxLayout.X_AXIS));
		
		JLabel srcJarLabel = new JLabel();
		srcJarLabel.setText("Jar File");
		srcJarField = new JTextField();
		JButton srcJarButton = new JButton();
		srcJarButton.setText("Browse...");
		srcJarButton.addActionListener(new ChooseFileListener());
		JLabel targetJarDirLabel = new JLabel();
		targetJarDirLabel.setText("Output Dir");
		targetJarDirField = new JTextField();
		JButton targetJarDirButton = new JButton();
		targetJarDirButton.setText("Browse...");
		targetJarDirButton.addActionListener(new ChooseTargetDirListener());
		
		JPanel f1Panel = new JPanel(false);
		f1Panel.setLayout(new BoxLayout(f1Panel,
				BoxLayout.Y_AXIS));
		f1Panel.add(srcJarLabel);
		f1Panel.add(targetJarDirLabel);
		
		JPanel f2Panel = new JPanel(false);
		f2Panel.setLayout(new BoxLayout(f2Panel,
				BoxLayout.Y_AXIS));
		f2Panel.add(srcJarField);
		f2Panel.add(targetJarDirField);
		
		JPanel f3Panel = new JPanel(false);
		f3Panel.setLayout(new BoxLayout(f3Panel,
				BoxLayout.Y_AXIS));
		f3Panel.add(srcJarButton);
		f3Panel.add(targetJarDirButton);
		
		filePanel.add(f1Panel);
		filePanel.add(f2Panel);
		filePanel.add(f3Panel);
		
		add(filePanel);
	}
	private void createVarPanel(JPanel parent){
		
		JPanel varPanel = new JPanel(false);
		parent.add(varPanel);
		varPanel.setLayout(new GridLayout(0,6));
		
   		databaseLabel = new JLabel();
		databaseLabel.setText("Database");
		databaseField = new JTextField();
		databaseField.setText("database");
     		factoryLabel = new JLabel();
		factoryLabel.setText("factory");
		factoryField = new JTextField();
		factoryField.setText("factory");
       factoryField.setEditable(false);
     		fileSubmitterLabel = new JLabel();
		fileSubmitterLabel.setText("FileSubmitter");
		fileSubmitterField = new JTextField();
		fileSubmitterField.setText("fileSubmitter");
     		localServerLabel = new JLabel();
		localServerLabel.setText("LocalServer");
		localServerField = new JTextField();
		localServerField.setText("localServer");
     		managedResourceStoreLabel = new JLabel();
		managedResourceStoreLabel.setText("ManagedResourceStore");
		managedResourceStoreField = new JTextField();
		managedResourceStoreField.setText("managedResourceStore");
     		resourceStoreLabel = new JLabel();
		resourceStoreLabel.setText("ResourceStore");
		resourceStoreField = new JTextField();
		resourceStoreField.setText("resourceStore");
     		resultSetLabel = new JLabel();
		resultSetLabel.setText("ResultSet");
		resultSetField = new JTextField();
		resultSetField.setText("resultSet");
     		workerPoolLabel = new JLabel();
		workerPoolLabel.setText("WorkerPool");
		workerPoolField = new JTextField();
		workerPoolField.setText("workerPool");
  		varPanel.add(databaseLabel);
		varPanel.add(databaseField);
		varPanel.add(factoryLabel);
		varPanel.add(factoryField);
		varPanel.add(fileSubmitterLabel);
		varPanel.add(fileSubmitterField);
		varPanel.add(localServerLabel);
		varPanel.add(localServerField);
		varPanel.add(managedResourceStoreLabel);
		varPanel.add(managedResourceStoreField);
		varPanel.add(resourceStoreLabel);
		varPanel.add(resourceStoreField);
		varPanel.add(resultSetLabel);
		varPanel.add(resultSetField);
		varPanel.add(workerPoolLabel);
		varPanel.add(workerPoolField);
		

	}
	private Map<String,String> getTypeVarMap(){
		Map<String,String> typeVar = new HashMap<String, String>();
		HashSet<String> allvars = new HashSet<String>();
        String database = databaseField.getText();
        String factory = factoryField.getText();
        String fileSubmitter = fileSubmitterField.getText();
        String localServer = localServerField.getText();
        String managedResourceStore = managedResourceStoreField.getText();
        String resourceStore = resourceStoreField.getText();
        String resultSet = resultSetField.getText();
        String workerPool = workerPoolField.getText();

		
        if(isValidVar(database,allvars)){
		    typeVar.put("Database",database);
		}else{
		    return null;
		}
        if(isValidVar(factory,allvars)){
		    typeVar.put("factory",factory);
		}else{
		    return null;
		}
        if(isValidVar(fileSubmitter,allvars)){
		    typeVar.put("FileSubmitter",fileSubmitter);
		}else{
		    return null;
		}
        if(isValidVar(localServer,allvars)){
		    typeVar.put("LocalServer",localServer);
		}else{
		    return null;
		}
        if(isValidVar(managedResourceStore,allvars)){
		    typeVar.put("ManagedResourceStore",managedResourceStore);
		}else{
		    return null;
		}
        if(isValidVar(resourceStore,allvars)){
		    typeVar.put("ResourceStore",resourceStore);
		}else{
		    return null;
		}
        if(isValidVar(resultSet,allvars)){
		    typeVar.put("ResultSet",resultSet);
		}else{
		    return null;
		}
        if(isValidVar(workerPool,allvars)){
		    typeVar.put("WorkerPool",workerPool);
		}else{
		    return null;
		}


	

		return typeVar;
	}
	private boolean isValidVar(String var,Set<String> vars){
		if (var == null || var.length() == 0){
			return false;
		}
		String[] vs = vars(var);
		for(String v:vs){
			
			if (vars.contains(var)){
				return false;
			} else {
				vars.add(v);
			}
		}
		return true;
		
	}
	private String chooseFile(){
		chooser.setMultiSelectionEnabled(false);
		chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		chooser.setFileFilter(new JarFileFilter());
		int retval = chooser.showDialog(frame, null);
		if (retval == JFileChooser.APPROVE_OPTION) {
			File theFile = chooser.getSelectedFile();
			
			String filePath = theFile.getAbsolutePath();
			filePath = filePath.replaceAll("\\\\", "/");
			return filePath;
		}
		return null;
	}
	private String chooseTargetDir(){
		chooser.setMultiSelectionEnabled(false);
		chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		chooser.setFileFilter(null);
		int retval = chooser.showDialog(frame, null);
		if (retval == JFileChooser.APPROVE_OPTION) {
			File theDir = chooser.getSelectedFile();
			String fileDir = theDir.getAbsolutePath();
			fileDir = fileDir.replaceAll("\\\\", "/");
			return fileDir;
		}
		return null;
	}
	
	private String[] vars(String var){
		String[] ss = var.split(",");
		List<String> sList = new ArrayList<String>();
		for(String s:ss){
			if (s.trim().length() == 0){
				continue;
			}
			sList.add(s.trim());
		}
		ss = new String[sList.size()];
		sList.toArray(ss);
		return ss;
	}
	private void test(JFrame frame){
		this.frame = frame;
		ExportJarDemo panel = new ExportJarDemo();
		frame.getContentPane().add("Center", panel);
		frame.pack();
		frame.setVisible(true);
	}
	class ChooseFileListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			String filePath = chooseFile();
			if  (filePath != null){
				srcJarField.setText(filePath);
			}
		}
	}
	class ChooseTargetDirListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			String dirPath = chooseTargetDir();
			if  (dirPath != null){
				targetJarDirField.setText(dirPath);
			}
		}
	}
	class GenerateAction implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			Map<String,String> typeVar = getTypeVarMap();
			File srcFile = new File(srcJarField.getText().trim());
			if (!srcFile.exists()){
				JOptionPane.showMessageDialog(frame, "Jar File does not exist", "failed", JOptionPane.WARNING_MESSAGE);
				return;
			}
			File targetDir = new File(targetJarDirField.getText().trim());
			if (!targetDir.exists()){
				JOptionPane.showMessageDialog(frame, "Output Dir does not exist", "failed", JOptionPane.WARNING_MESSAGE);
				return;
			}
			
			InputStream is = IOUtils.class.getResourceAsStream("gearsapi");
			try {
				Map gmapapi = (Map)IOUtils.readObject(is);
				Comparator<String> comparator = new Comparator<String>(){

					public int compare(String o1, String o2) {
						return o1.compareTo(o2);
					}
				};
				Map<String, Map<String, Map>> orderH2Map = new TreeMap<String, Map<String,Map>>(comparator);
				orderH2Map.putAll(gmapapi);
				IOUtils.appendToJar(srcFile, targetDir, orderH2Map, typeVar);
				JOptionPane.showMessageDialog(frame, "generate success", "Message", JOptionPane.INFORMATION_MESSAGE);
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (ClassNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
		}
	}
	class JarFileFilter extends FileFilter {

		@Override
		public boolean accept(File f) {
			if (f.isDirectory()){
				return true;
			}
			String filename = f.getName();
			if (!filename.startsWith("org.eclipse.wst.javascript.ui")){
				return false;
			}
			if (!filename.endsWith(".jar")){
				return false;
			}
			return true;
		}

		@Override
		public String getDescription() {
			// TODO Auto-generated method stub
			return "org.eclipse.wst.javascript.ui_?????.jar";
		}
		
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		JFrame frame = new JFrame("FileChooserDemo");
		frame.addWindowListener(new WindowAdapter() {
		    public void windowClosing(WindowEvent e) {System.exit(0);}
		});
		ExportJarDemo panel = new ExportJarDemo();
		panel.test(frame);

	}
	

}
